﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Game
{
    //
    //
    //
    public class LoadingState : StateBase
    {

        public LoadingState(DataBase.Manager DataBaseManager)
            : base(DataBaseManager)
        {
            LevelId = 8; // is defualt 13
        }

        public UInt32 LevelId
        {
            get;
            set;
        }

        public override void Activate()
        {
            GameScene.Engine.Lock(true);

            DataBaseManager.LoadMap(LevelId);

            LoadMap(DataBaseManager.GetMaps()[LevelId].name);

            GameScene.Engine.Unlock();
        }

        protected void LoadMap(String name)
        {
            //add view cam
            IDK.ThirdPersonCamera camera = new IDK.ThirdPersonCamera();

            RenderTechnique.TechniqueDescription desc = new RenderTechnique.TechniqueDescription(GameScene.Core, GameScene.Renderer, camera);

            //GameScene.Technique = new RenderTechnique.DebugRenderTechnique(desc);
            GameScene.Technique = new RenderTechnique.ForwardTechnique(desc);
            //GameScene.Technique = new RenderTechnique.DeferredTechnique(desc);
            GameScene.Technique.Init();

            //Load physic static mesh
            //GameScene.LoadCollisonMap(name);

            //Load object's
            Dictionary<uint, IDK.SceneNode> cacheNodes = new Dictionary<uint, IDK.SceneNode>();

            var mapObjects = DataBaseManager.GetMapObjects();

            if (ProgressBar != null)
            {
                ProgressBar.Value = 0;
                ProgressBar.Count = mapObjects.Count;
                ProgressBar.Caption = "Loading...";
            }

            foreach (KeyValuePair<UInt32, DataBase.Entities.MapObject> it in mapObjects)
            {
                DataBase.Entities.MapObject item = it.Value;
                //
                AddMapObject(item, cacheNodes);

                if (ProgressBar != null)
                {
                    ProgressBar.Value = ProgressBar.Value + 1;
                }
            }

            Log.Hint("Map prepared");
            
            //Force update transformation
            GameScene.Core.GetScene().Update();

            //Create managers
            GameScene.AddManager(new AICharacterManager());
            GameScene.AddManager(new GameObjectManager());

            LoadGameObject(name);

            var gameObjectManager = GameScene.GetManager<GameObjectManager>();

            GameScene.TriggerEventSystem.AddListener(gameObjectManager);
            GameScene.HitEventSystem.AddListener(gameObjectManager);
            //attach to scene trigger 

            GameScene.Camera = camera;

            OnLoadMap(camera);

            //meake game object
            foreach (KeyValuePair<UInt32, DataBase.Entities.MapObject> it in mapObjects)
            {
                DataBase.Entities.MapObject item = it.Value;

                if (gameObjectManager.HasGameObject(item.name))
                {
                    gameObjectManager.CreateGameObject(item.name, GameScene);
                }
            }
        }

        protected virtual void LoadGameObject(String name)
        {
            //?
        }

        protected virtual void OnLoadMap(IDK.ThirdPersonCamera camera)
        {
        }

        public override void Deactivate()
        {
            GameScene = null;
        }

        public override Transition Update(Events.ProcessUpdate evnt)
        {
            return Transition.Next;
        }
    }

    //
    //
    //
    public class UnloadingState : StateBase
    {
        public UnloadingState(DataBase.Manager DataBaseManager)
            : base(DataBaseManager)
        {
        }


        public override void Activate()
        {
            //clear map objects db data
            DataBaseManager.UnloadMapObjects();

            GameScene.ActionManager.Clear();
            GameScene.ActionManager.InputSubscriber.Clear();

            IDK.Engine engine = GameScene.Engine;
            IDK.Core core = GameScene.Core;
            IDK.Renderer renderer = GameScene.Renderer;

            //free
            GameScene = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
            Log.Warn("Managed total memory using :" + ((float)GC.GetTotalMemory(true) / (1024.0f * 1024.0f)).ToString() + " mb");

            //Lock Engine
            engine.Lock(true);

            renderer.ClearPasses();
            core.Clear();

            engine.Unlock();
        }

        public override void Deactivate()
        {
            //release scene
            GameScene = null;
        }

        public override Transition Update(Events.ProcessUpdate evnt)
        {
            return Transition.Next;
        }
    }
}
